package com.marvels.financial.loan.service.impl;

import com.alibaba.fastjson.JSON;
import com.fintech.common.util.DateTimeUtil;
import com.github.pagehelper.util.StringUtil;
import com.marvels.common.dto.MarvelsApiResultDTO;
import com.marvels.common.dto.pay.McfePaymentUserBindCard;
import com.marvels.common.exception.MarvelsApiBusinessException;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.exception.MarvelsErrorCode;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.GenerateReqNoUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;
import com.marvels.financial.consum.FinancialConsumerProductApi;
import com.marvels.financial.consum.FinancialConsumerUmApi;
import com.marvels.financial.loan.api.FinancialILoanAfterInfoApi;
import com.marvels.financial.loan.dao.ReimbursementProcessDao;
import com.marvels.financial.loan.dto.*;
import com.marvels.financial.loan.service.ReimbursementProcessService;
import com.marvels.financial.loan.service.ReplacePaymentApi;
import com.marvels.financial.loan.service.TransferPaymentApi;
import com.marvels.financial.loan.service.WithholdPaymentApi;
import com.marvels.financial.pay.dao.McfePaymentUserBindCardMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

@Service
public class ReimbursementProcessServiceImpl implements ReimbursementProcessService {
	@Autowired
	private ReimbursementProcessDao reimbursementProcessDao;
	@Autowired
	private FinancialConsumerUmApi consumerUmApi;
	@Autowired
	private FinancialConsumerProductApi consumerProductApi;
	@Autowired
	private WithholdPaymentApi withholdPaymentApi;
	@Autowired
	private TransferPaymentApi transferPaymentApi;
	@Autowired
	private FinancialILoanAfterInfoApi iLoanAfterInfoApi;

	@Value("${config.properties.path}")
	private  String configPropertiesPath;

	@Autowired
	private com.marvels.financial.loan.dao.McfeCustomerLoanContractDao customerLoanContractDao;

	@Autowired
	private McfePaymentUserBindCardMapper mcamPaymentUserBindCardMapper;
	@Autowired
	private ReplacePaymentApi replacePaymentApi;

	@Override
	public Map getRepayInfo(RepaymentNoMobileDTO repaymentNoMobileDTO) throws MarvelsBusinessException{
		MarvelsLogUtil.getInstance().info("getrepayInfo >>>>>>>>>>>>>>>>>>>>");
		Map<String, Object> returnMapInfo = new HashMap<String, Object>();
		if (null == repaymentNoMobileDTO.getUserId() ) {
			return returnMapInfo;
		}
		RealNameAuthentication realName = consumerUmApi.queryByUserId(repaymentNoMobileDTO.getUserId());
		try {
			if (realName == null) {
				return returnMapInfo;
			}
			 returnMapInfo = queryReturnInfo(realName.getIdentityCardNo());
				if(returnMapInfo==null){
					return returnMapInfo;
				}
			//提前结清时获取相关数据
			// AmountDTO res = iLoanAfterInfoApi.prePayTrail(returnMapInfo.get("loanId").toString());
			// BigDecimal amount = (BigDecimal) res.getPreAmount();
			// returnMapInfo.put("earlySettlement", amount);//提前还清
			//剩余本金
			returnMapInfo.put("surplusCapital",returnMapInfo.get("principalOs"));
//			BigDecimal liquidatedDamages = amount.subtract(new BigDecimal(returnMapInfo.get("principalOs")+"")).
//				subtract(new BigDecimal(returnMapInfo.get("currentReturnMoney")+""));
//			returnMapInfo.put("liquidatedDamages",liquidatedDamages.doubleValue());//违约金
			String status = reimbursementProcessDao.queryPlanIdStatus(realName.getIdentityCardNo());
			MarvelsLogUtil.getInstance().info("查询是否有在途还款:"+status);
			if(StringUtils.isEmpty(status)||StringUtils.equals("9", status)||StringUtils.equals("2", status)){
				returnMapInfo.put("isSubmit", true);//只有交易关闭后才可以再次提交
			}else{
				returnMapInfo.put("isSubmit", false);
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("getrepayInfo==>>",e);
			throw new MarvelsBusinessException("getRepayInfo");
		}
		return returnMapInfo;
	}
	@Override
	public List<Map<String,Object>> selectRepaymentHistory(RepaymentNoMobileDTO repaymentNoMobileDTO){
		List<Map<String,Object>> withholdList = new ArrayList();
		RealNameAuthentication realName = new RealNameAuthentication();
		realName = consumerUmApi.queryByUserId(repaymentNoMobileDTO.getUserId());
		McfePaymentWithholdDTO mcfePaymentWithholdDTO = new McfePaymentWithholdDTO();
		if(realName != null){
			mcfePaymentWithholdDTO.setCustCardNo(realName.getIdentityCardNo());
			withholdList = reimbursementProcessDao.selectMcfePaymentWithhold(mcfePaymentWithholdDTO);
		}
		return withholdList;
	}

	@Override
	public List<Map> penaltyAdjustmentList(RepaymentNoMobileDTO repaymentNoMobileDTO) {
		List list = reimbursementProcessDao.penaltyAdjustmentList(repaymentNoMobileDTO.getOrgTransctionSeq());
		return list;
	}

	@Override
	public Map selectDetailsRepayment(@RequestBody RepaymentNoMobileDTO repaymentNoMobileDTO)  throws MarvelsBusinessException{
		MarvelsLogUtil.getInstance().info(">>>>>>>>selectDetailsRepayment"+repaymentNoMobileDTO.getContractId()+"开始查询应还款明细数据");
		String contractId=repaymentNoMobileDTO.getContractId()+"";
		Map<String,Object> map = new HashMap<String,Object>();
		try {
			List<Map<String, Object>> currentList = new ArrayList<Map<String, Object>>();
			Map<String,Object> nextMap = new HashMap<String,Object>();
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			List<Map> planList = reimbursementProcessDao.selectMcfeCustomerRepaymentPlan(contractId);
			for(Map<String,Object> cMap:planList){
				Map<String,Object> tmpMap = new HashMap<String,Object>();
				tmpMap.put("paymentDate", cMap.get("paymentDate"));
				tmpMap.put("tenor", cMap.get("tenor"));
				List<Map<String,Object>> moneyList = new ArrayList<Map<String,Object>>();
				Map<String,Object> tMap = new HashMap<String,Object>();
				tMap.put("name","penaltyFee1");
				tMap.put("amount", cMap.get("penaltyFee1"));
				moneyList.add(tMap);
				tMap = new HashMap<String,Object>();
				tMap.put("name","penaltyFee2");
				tMap.put("amount", cMap.get("penaltyFee2"));
				moneyList.add(tMap);
				tMap = new HashMap<String,Object>();
				tMap.put("name","serviceFee2");
				tMap.put("amount", cMap.get("serviceFee2"));
				moneyList.add(tMap);
				tMap = new HashMap<String,Object>();
				tMap.put("name","principal");
				tMap.put("amount", cMap.get("principal"));
				moneyList.add(tMap);
				tMap = new HashMap<String,Object>();
				tMap.put("name","interest");
				tMap.put("amount", cMap.get("interest"));
				moneyList.add(tMap);
				tmpMap.put("repaymentList", moneyList);
				list.add(tmpMap);
			}
			MarvelsLogUtil.getInstance().info(">>>>>>>>selectDetailsRepayment***开始计算提前结清明细**"+planList.get(0).get("loanId"));
			//查看提前结清明细
			List<Map<String, Object>> prelist = new ArrayList<Map<String, Object>>();
			if(CollectionUtils.isNotEmpty(planList) && !planList.get(0).get("fundCode").toString().equals("14")){
				List<McfeCustomerRepaymentPlanDTO> mpList = reimbursementProcessDao.selectOverPlan(planList.get(0).get("loanId").toString());
				List<Map> AllUncompleted = reimbursementProcessDao.selectMcfeCustomerRepaymentPlan(contractId);
				McfeCustomerRepaymentPlanDTO mp=null;
				int ten = 0;//取出当期应还,也就是所有还款计划中第一个A0状态的记录
				Boolean whe = false;
				if(mpList!=null&&mpList.size()>0){
					mp = mpList.get(mpList.size()-1);
					ten = mp.getTenor()+1;
				}else{
					Map<String, Object> map2 = AllUncompleted.get(0);
					Calendar ca = Calendar.getInstance();
					ca.add(Calendar.MONTH, 1);
					McfeCustomerLoanContractDTO mpc = reimbursementProcessDao.selectMcfeCustomerLoanContract(contractId);
					if(mpc!=null){
						if(ca.getTime().compareTo((Date)map2.get("paymentDate"))<=0){
							ten = mpc.getCurrTenor();
							whe = true;
						}else{
							ten = mpc.getCurrTenor()+1;
						}
					}
				}
				MarvelsLogUtil.getInstance().info(">>>>>>>>selectDetailsRepayment***符合条件的数据来计处提前结清费**"+planList.get(0).get("loanId"));
				//条用提前结清金额获取提前结清费
				AmountDTO res = iLoanAfterInfoApi.prePayTrail(planList.get(0).get("loanId").toString());
				BigDecimal preFee = new BigDecimal(BigInteger.ZERO);
				if(res!=null){
					preFee=(BigDecimal)res.getPreFee();
				}
				for(Map<String,Object> plan:AllUncompleted){
					Map<String,Object> tmpMap = new HashMap<String,Object>();
					tmpMap.put("paymentDate", plan.get("paymentDate"));
					tmpMap.put("tenor", plan.get("tenor"));
					List<Map<String,Object>> moneyList = new ArrayList<Map<String,Object>>();
					Map<String,Object> tMap = new HashMap<String,Object>();
					tMap.put("name","principal");
					tMap.put("amount", plan.get("principal"));
					moneyList.add(tMap);
					if(whe){
						tMap = new HashMap<String,Object>();
						tMap.put("name","preFee");
						tMap.put("amount", preFee);
						moneyList.add(tMap);
						whe=false;
					}
					if("1".equals(plan.get("status"))||ten == Integer.parseInt((plan.get("tenor")+""))){
						if(ten == Integer.parseInt((plan.get("tenor")+""))){
							tMap = new HashMap<String,Object>();
							tMap.put("name","preFee");
							tMap.put("amount", preFee);
							moneyList.add(tMap);
						}
					tMap = new HashMap<String,Object>();
					tMap.put("name","penaltyFee1");
					tMap.put("amount", plan.get("penaltyFee1"));
					moneyList.add(tMap);
					tMap = new HashMap<String,Object>();
					tMap.put("name","penaltyFee2");
					tMap.put("amount", plan.get("penaltyFee2"));
					moneyList.add(tMap);
					tMap = new HashMap<String,Object>();
					tMap.put("name","serviceFee2");
					tMap.put("amount", plan.get("serviceFee2"));
					moneyList.add(tMap);
					tMap = new HashMap<String,Object>();
					tMap.put("name","interest");
					tMap.put("amount", plan.get("interest"));
					moneyList.add(tMap);
					}
					tmpMap.put("repaymentList", moneyList);
					prelist.add(tmpMap);
				}
			}
			if(list==null||list.size()==0){//无还款信息
				return null;
			}
			MarvelsLogUtil.getInstance().info(">>>>>>>>selectDetailsRepayment***计算最后一期金额**"+planList.get(0).get("loanId"));
			if(list.size()==1&& DateTimeUtil.compareDay(new Date(), ">=", (Date)list.get(0).get("paymentDate") ) ){//最后一期还款
				currentList.add(list.get(0));
				map.put("currentList", currentList);
				map.put("nextMap", nextMap);
				map.put("NoPaymentList", list);
				map.put("prelist",prelist);
				return map;
			}
			if("1".equals(list.get(0).get("tenor")+"")&&DateTimeUtil.compareDay(new Date(), "<", (Date)list.get(0).get("paymentDate"))){//如果是第一次还款的时间还没有到
				nextMap=list.get(0);
				map.put("nextMap", nextMap);
				map.put("currentList", currentList);
				map.put("NoPaymentList", list);
				map.put("prelist",prelist);
				return map;
			}
			for (Map<String, Object> planMap : list) {
				Date paymentDate= DateUtils.truncate((Date)planMap.get("paymentDate"), Calendar.DAY_OF_MONTH);
				if(DateTimeUtil.compareDay(paymentDate, "<=", new Date())){
					currentList.add(planMap);
				}else{
					nextMap=planMap;
					break;
				}
			}
			map.put("currentList", currentList);
			map.put("nextMap", nextMap);
			map.put("NoPaymentList", list);
			map.put("prelist",prelist);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("计算数据时出错了*******",e);
			new MarvelsBusinessException("计算数据时出错了*******",e);
		}
		MarvelsLogUtil.getInstance().info(">>>>>>>>selectDetailsRepayment***END**"+contractId);
		return map;
	}

	/**
	 * 用身份证查还款计划数据
	 * @param custCardNo
	 * @return
	 */
	public Map queryReturnInfo(String custCardNo)throws MarvelsBusinessException{
		Map returnInfo= new LinkedHashMap();
		List<Map> list=reimbursementProcessDao.queryReturnInfo(custCardNo);
		if(CollectionUtils.isEmpty(list)){//无还款计划信息
			return null;
		}
		if(list.size()==1 && DateTimeUtil.compareDay(new Date(), ">=", (Date)list.get(0).get("paymentDate") ) ){//最后一期还款
			returnInfo=list.get(0);
			returnInfo.put("nextPeriodsReturnMoney", null);
			returnInfo.put("nextPeriodsDate", null);
			returnInfo.put("nextPlanId", list.get(0).get("planCode"));
			return returnInfo;
		}
		if("1".equals(list.get(0).get("tenor")+"")&&DateTimeUtil.compareDay(new Date(), "<", (Date)list.get(0).get("paymentDate") )){//如果是第一次还款的时间还没有到
			returnInfo=list.get(0);
			returnInfo.put("nextPeriodsReturnMoney", returnInfo.get("currentReturnMoney")+"");
			returnInfo.put("nextPeriodsDate", returnInfo.get("paymentDate"));
			returnInfo.put("nextPlanId", returnInfo.get("planCode"));
			returnInfo.put("currentReturnMoney", 0);
			returnInfo.put("management_fee", 0);
			returnInfo.put("fine", 0);
			returnInfo.put("current_return_bx", 0);
			return returnInfo;
		}

		BigDecimal currentReturnMoney = new BigDecimal(0);
		BigDecimal managementFee=new BigDecimal(0);
		BigDecimal fine=new BigDecimal(0);
		BigDecimal currentReturnBx=new BigDecimal(0);
		//遍历还款计划
		for (Map<String, Object> planMap : list) {
			Date paymentDate= DateUtils.truncate((Date)planMap.get("paymentDate"), Calendar.DAY_OF_MONTH);
			if(DateTimeUtil.compareDay(paymentDate, "<=", new Date())){
				MarvelsLogUtil.getInstance().info("DateTimeUtil.compareDay==>>true:"+paymentDate);
				returnInfo.put("currentReturnMoney", currentReturnMoney.add(new BigDecimal(planMap.get("currentReturnMoney")+"")));
				returnInfo.put("management_fee", managementFee.add(new BigDecimal(planMap.get("managementFee")+"")));
				returnInfo.put("fine", fine.add(new BigDecimal(planMap.get("fine")+"")));
				returnInfo.put("current_return_bx", currentReturnBx.add(new BigDecimal(planMap.get("currentReturnBx")+"")));
				returnInfo.put("contractId", planMap.get("contractId"));
				returnInfo.put("tenor", planMap.get("tenor"));
				returnInfo.put("applyMoney", planMap.get("applyMoney"));
				returnInfo.put("create_time", planMap.get("applyTime"));
				returnInfo.put("loanId", planMap.get("loanId"));
				returnInfo.put("src_case_id", planMap.get("loanId"));
				returnInfo.put("cust_id_card", planMap.get("custCardNo"));
				returnInfo.put("planId", planMap.get("planCode"));
				/*returnInfo.put("customerId", planMap.get("customerId"));*/
				returnInfo.put("product_id", planMap.get("productType"));
				returnInfo.put("repay_acct", planMap.get("repayAcct"));
				returnInfo.put("repay_bank_name", planMap.get("paymentBankName"));
				returnInfo.put("status", planMap.get("status"));
				returnInfo.put("paymentDate", planMap.get("paymentDate"));
				returnInfo.put("principalOs", planMap.get("principalOs"));

			}else{
				MarvelsLogUtil.getInstance().info("DateTimeUtil.compareDay==>>false:"+paymentDate);
				if(returnInfo.get("currentReturnMoney")!=null&&!"".equals(returnInfo.get("currentReturnMoney")+"")){
					returnInfo.put("currentReturnMoney", returnInfo.get("currentReturnMoney"));
				}else{
					returnInfo.put("currentReturnMoney", 0);
				}
				returnInfo.put("contractId", planMap.get("contractId"));
				returnInfo.put("nextTenor", planMap.get("tenor"));
				returnInfo.put("applyMoney", planMap.get("applyMoney"));
				returnInfo.put("create_time", planMap.get("applyTime"));
				returnInfo.put("src_case_id", planMap.get("loanId"));
				returnInfo.put("cust_id_card", planMap.get("custCardNo"));
				/*returnInfo.put("customerId", planMap.get("customerId"));*/
				returnInfo.put("product_id", planMap.get("productType"));
				returnInfo.put("repay_acct", planMap.get("repayAcct"));
				returnInfo.put("repay_bank_name", planMap.get("paymentBankName"));
				returnInfo.put("status", planMap.get("status"));
				returnInfo.put("principalOs", planMap.get("principalOs"));
				if(null==returnInfo.get("planCode") || StringUtils.isEmpty(returnInfo.get("planCode").toString())){
					returnInfo.put("planCode", planMap.get("planCode"));
				}
				String planMoney = planMap.get("currentReturnMoney")+"";
				returnInfo.put("nextPeriodsReturnMoney", planMoney);
				returnInfo.put("nextPeriodsDate", planMap.get("paymentDate"));
				returnInfo.put("nextPlanId", planMap.get("planCode"));
				break;
			}
		}
		return returnInfo;
	}


	@Override
	public List<ShouldRepaymentDTO> selectPaymentInformation(RepaymentNoMobileDTO repaymentNoMobileDTO) throws MarvelsBusinessException {
		List<ShouldRepaymentDTO> list = null;
		try {
			MarvelsLogUtil.getInstance().info("ReimbursementProcessServiceImpl.selectPaymentInformation param==>"+JSON.toJSONString(repaymentNoMobileDTO));
			list = reimbursementProcessDao.getOnwayRayment(repaymentNoMobileDTO.getLoanId(),repaymentNoMobileDTO.getCustCardNo());
			MarvelsLogUtil.getInstance().info("cust on way rayment list ===>" + JSON.toJSONString(list));
		}catch (Exception e) {
			MarvelsLogUtil.getInstance().error("查询应还款信息异常",e);
		}
		return list;
	}

	@Deprecated
	public Map queryReturnInfoByLoanId(Map map) {
		Map returnInfo= new HashMap();
		List<Map> list=reimbursementProcessDao.queryReturnInfoByLoanId(map.get("loanId").toString());
		if(list==null||list.size()==0){//无还款信息
			return null;
		}
		BigDecimal currentReturnMoney = new BigDecimal(0);
		BigDecimal management_fee=new BigDecimal(0);
		BigDecimal fine=new BigDecimal(0);
		BigDecimal current_return_bx=new BigDecimal(0);
		if("14".equals(map.get("fundCode").toString())){//盛大小贷资金源
			Map oneMap = list.get(0);
			Date now = new Date();
			Date payDate = (Date)oneMap.get("paymentDate");
			if(now.getTime()>(payDate.getTime()+5*24*60*60*1000)){//逾期并且在5天之后不展示还款
				return null;
			}
		}
		if(list.size()==1 && DateTimeUtil.compareDay(new Date(), ">=", (Date)list.get(0).get("paymentDate") ) ){//最后一期还款
			returnInfo=list.get(0);
			returnInfo.put("nextPeriodsReturnMoney", null);
			returnInfo.put("nextPeriodsDate", null);
			returnInfo.put("nextPlanId", list.get(0).get("planId"));
			returnInfo.put("productType", list.get(0).get("productType"));
			returnInfo.put("productName", list.get(0).get("productName"));
			return returnInfo;
		}
		if("1".equals(list.get(0).get("tenor")+"")&&DateTimeUtil.compareDay(new Date(), "<", (Date)list.get(0).get("paymentDate") )){//如果是第一次还款的时间还没有到
			returnInfo=list.get(0);
			String planMoney = returnInfo.get("currentReturnMoney")+"";
			returnInfo.put("nextPeriodsReturnMoney", planMoney);
			returnInfo.put("nextPeriodsDate", returnInfo.get("paymentDate"));
			returnInfo.put("nextPlanId", returnInfo.get("planId"));
			returnInfo.put("currentReturnMoney", 0);
			returnInfo.put("management_fee", 0);
			returnInfo.put("fine", returnInfo.get("fine"));
			returnInfo.put("current_return_bx", 0);
			returnInfo.put("productType", list.get(0).get("productType"));
			returnInfo.put("productName", list.get(0).get("productName"));
			return returnInfo;
		}
		//遍历还款计划
		for (Map planMap : list) {
			Date paymentDate= DateUtils.truncate((Date)planMap.get("paymentDate"), Calendar.DAY_OF_MONTH);
			if(new Date().compareTo(paymentDate)>=0){
				currentReturnMoney = currentReturnMoney.add(new BigDecimal(planMap.get("currentReturnMoney")+""));
				management_fee=management_fee.add(new BigDecimal(planMap.get("managementFee")+""));
				fine=fine.add(new BigDecimal(planMap.get("fine")+""));
				current_return_bx.add(new BigDecimal(planMap.get("currentReturnBx")+""));
				returnInfo.put("currentReturnMoney", currentReturnMoney);
				returnInfo.put("management_fee", management_fee);
				returnInfo.put("fine", fine);
				returnInfo.put("current_return_bx", current_return_bx);
				returnInfo.put("contractId", planMap.get("contractId"));
				returnInfo.put("tenor", planMap.get("tenor"));
				returnInfo.put("applyMoney", planMap.get("applyMoney"));
				returnInfo.put("src_case_id", planMap.get("src_case_id"));
				returnInfo.put("cust_id_card", planMap.get("cust_id_card"));
				returnInfo.put("planId", planMap.get("planId"));
				/*returnInfo.put("create_time", planMap.get("create_time"));*/
				/*returnInfo.put("customerId", planMap.get("customerId"));*/
				returnInfo.put("product_id", planMap.get("productId"));
				returnInfo.put("repay_acct", planMap.get("repay_acct"));
				returnInfo.put("repay_bank_name", planMap.get("repay_bank_name"));
				returnInfo.put("status", planMap.get("status"));
				returnInfo.put("paymentDate", planMap.get("paymentDate"));
				returnInfo.put("principalOs", planMap.get("principalOs"));
				returnInfo.put("productType", planMap.get("productType"));
				returnInfo.put("productName", planMap.get("productName"));
			}else{
				if(returnInfo.get("currentReturnMoney")!=null&&!"".equals(returnInfo.get("currentReturnMoney")+"")){
					returnInfo.put("currentReturnMoney", returnInfo.get("currentReturnMoney"));
				}else{
					returnInfo.put("currentReturnMoney", 0);
				}
				returnInfo.put("contractId", planMap.get("contractId"));
				returnInfo.put("nextTenor", planMap.get("tenor"));
				returnInfo.put("applyMoney", planMap.get("applyMoney"));
				/*returnInfo.put("create_time", planMap.get("create_time"));*/
				/*returnInfo.put("customerId", planMap.get("customerId"));*/
				returnInfo.put("src_case_id", planMap.get("loanId"));
				returnInfo.put("cust_id_card", planMap.get("cust_id_card"));
				returnInfo.put("product_id", planMap.get("productId"));
				returnInfo.put("repay_acct", planMap.get("repay_acct"));
				returnInfo.put("repay_bank_name", planMap.get("repay_bank_name"));
				returnInfo.put("principalOs", planMap.get("principalOs"));
				if(null==returnInfo.get("planId") || StringUtils.isEmpty(returnInfo.get("planId").toString())){
					returnInfo.put("planId", planMap.get("planId"));
				}
				String planMoney = planMap.get("currentReturnMoney")+"";
				returnInfo.put("nextPeriodsReturnMoney", planMoney);
				returnInfo.put("nextPeriodsDate", planMap.get("paymentDate"));
				returnInfo.put("nextPlanId", planMap.get("planId"));
				returnInfo.put("productType", planMap.get("productType"));
				returnInfo.put("productName", planMap.get("productName"));
				break;
			}
		}
		return returnInfo;
	}



	@Override
	public MarvelsApiResultDTO repaymentNoMobile(RepaymentNoMobileDTO repaymentNoMobileDTO) throws Exception {
		//检查loanId是否为空
		if(repaymentNoMobileDTO == null || StringUtil.isEmpty(repaymentNoMobileDTO.getLoanId())) {
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"申请编号为空");
		}

		//定义返回对象
		MarvelsApiResultDTO resultDto = null;
		String redistKey = null;
		boolean isLock = false;
		try {
			/**
			 * 通过redis分布式事务锁进行防重复提交
			 */
			redistKey = "repayment_lock_"+ repaymentNoMobileDTO.getLoanId();
			isLock = CacheUtils.isNotLock(redistKey, repaymentNoMobileDTO.getLoanId());
			if(isLock){
				CacheUtils.setExpire(redistKey, 300);//设置过期时间
			}else{
				throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"您有一笔代扣未完成请稍后再试!");
			}

			//组装代扣DTO
			McfePaymentWithholdDTO paymentWithhold = new McfePaymentWithholdDTO();
			paymentWithhold.setWithholdCategory("1");//还款代扣
			//查询合同信息
			McfeCustomerLoanContractDTO contract = new McfeCustomerLoanContractDTO();
			contract.setLoanId(repaymentNoMobileDTO.getLoanId());
			List<McfeCustomerLoanContractDTO> contracts = customerLoanContractDao.selectLoanContract(contract);
			if(contracts == null || contracts.size()!=1) {
				 throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"未找到还款的合同!");
			}
			McfeCustomerLoanContractDTO contractDto = contracts.get(0);

			//设置还款客户基本信息
			paymentWithholdDTO(contractDto,repaymentNoMobileDTO,paymentWithhold);

			BigDecimal tenorMoney = BigDecimal.ZERO;
			//设置应还款金额
			if(StringUtils.equalsIgnoreCase("A003", repaymentNoMobileDTO.getPayType())) {
				tenorMoney = iLoanAfterInfoApi.queryRepaymentAllMoney(repaymentNoMobileDTO.getLoanId());
			}else{
				// 重写应还金额
				ReplacePaymentConditionDto replacePaymentConditionDto = new ReplacePaymentConditionDto();
				replacePaymentConditionDto.setLoanId(repaymentNoMobileDTO.getLoanId());
				EarlyPaymentCalculatDto earlyPaymentCalculatDto = replacePaymentApi.calculatEarlypayment(replacePaymentConditionDto);
//				tenorMoney = iLoanAfterInfoApi.queryCurrentTenorMoney(repaymentNoMobileDTO.getLoanId());
				tenorMoney = earlyPaymentCalculatDto.getRemianCost();
			}
			if(repaymentNoMobileDTO.getAmount().compareTo(BigDecimal.ZERO)<0){
				throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"申请金额不能小于0");
			}
			if(repaymentNoMobileDTO.getAmount().compareTo(tenorMoney)>0){
				throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"申请金额不能大于应还金额");
			}
			paymentWithhold.setAmount(repaymentNoMobileDTO.getAmount());
			MarvelsLogUtil.getInstance().info("前端冲账 ===>data" + JSON.toJSONString(paymentWithhold));

//			// 根据类型选择还款类型
//			if("1".equals(repaymentNoMobileDTO.getRepayType())){
				//发起代扣
				resultDto = commonPaymentWithhold(paymentWithhold);
//			}else{
//				resultDto = commonPaymentTransfer(paymentWithhold);
//			}

			//转换成app需要的状态
			if(StringUtils.equalsIgnoreCase(resultDto.getCode(), MarvelsErrorCode.PROCESSING.getValue())){
				resultDto.setCode("2");
			}else if(StringUtils.equalsIgnoreCase(resultDto.getCode(), MarvelsErrorCode.SUCCESS.getValue())){
				resultDto.setCode("0");
			}else if(StringUtils.equalsIgnoreCase(resultDto.getCode(), MarvelsErrorCode.FAIL.getValue())){
				resultDto.setCode("1");
			}else{
				resultDto.setCode("2");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			if(isLock){
				CacheUtils.del(redistKey);
			}
		}
		return resultDto;
	}

	private  MarvelsApiResultDTO commonPaymentWithhold(McfePaymentWithholdDTO paymentWithhold)throws MarvelsApiBusinessException {
		BigDecimal amount = paymentWithhold.getAmount();
		int payType =  paymentWithhold.getPayType();
		String repayType = paymentWithhold.getRepayStyle();
		if(payType == 0 || StringUtils.isEmpty(repayType)){
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"还款方式不能为空");
		}
		if(BigDecimal.ZERO.compareTo(amount)>0) {
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"需要还款0元");
		}
		try {
			PaymentResponse resp = withholdPaymentApi.withholdCommonDeal(paymentWithhold);
			MarvelsLogUtil.getInstance().info("resp:"+resp.toString());
			if(resp == null) {
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.PROCESSING.getValue(), "处理中请稍后查询结果", null, null, null);
			}
			String code = resp.getCode();
			if("0".equals(code)) {//成功
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), resp.getMsg(), null, null, null);
			}else if("1".equals(code)) {//处理中
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.PROCESSING.getValue(), resp.getMsg(), null, null, null);
			}else {//失败
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.FAIL.getValue(), resp.getMsg(), null, null, null);
			}
		} catch (MarvelsBusinessException e) {
			MarvelsLogUtil.getInstance().error("commonPaymentWithhold通用还款loanId:"+paymentWithhold.getLoanId(),e);
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),e.getMessage());
		}
	}

	private  MarvelsApiResultDTO commonPaymentTransfer(McfePaymentWithholdDTO paymentWithhold)throws MarvelsApiBusinessException {
		BigDecimal amount = paymentWithhold.getAmount();
		int payType =  paymentWithhold.getPayType();
		String repayType = paymentWithhold.getRepayStyle();
		if(payType == 0 || StringUtils.isEmpty(repayType)){
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"还款方式不能为空");
		}
		if(BigDecimal.ZERO.compareTo(amount)>0) {
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"需要还款0元");
		}
		try {
			PaymentResponse resp = transferPaymentApi.withholdCommonDeal(paymentWithhold);
			if(resp == null) {
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.PROCESSING.getValue(), "处理中请稍后查询结果", null, null, null);
			}
			String code = resp.getCode();
			if("0".equals(code)) {//成功
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), resp.getMsg(), null, null, null);
			}else if("1".equals(code)) {//处理中
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.PROCESSING.getValue(), resp.getMsg(), null, null, null);
			}else {//失败
				return MarvelsApiResultDTO.getResult(MarvelsErrorCode.FAIL.getValue(), resp.getMsg(), null, null, null);
			}
		} catch (MarvelsBusinessException e) {
			MarvelsLogUtil.getInstance().error("commonPaymentWithhold通用还款loanId:"+paymentWithhold.getLoanId(),e);
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),e.getMessage());
		}
	}

	//组装公共参数
	private void paymentWithholdDTO(McfeCustomerLoanContractDTO contractDto ,RepaymentNoMobileDTO repaymentNoMobileDTO,McfePaymentWithholdDTO paymentWithhold) throws MarvelsApiBusinessException{
		String type=repaymentNoMobileDTO.getWithholdWay();
		paymentWithhold.setStatus("0");
		paymentWithhold.setType(type);
		paymentWithhold.setTransctionSeq(GenerateReqNoUtils.transctionReq("DK"));
		paymentWithhold.setChannelCode(contractDto.getChannelCode());
		paymentWithhold.setChannelName(contractDto.getChannelName());
		paymentWithhold.setFundCode(contractDto.getFundCode());
		paymentWithhold.setFundName(contractDto.getFundName());
		paymentWithhold.setLoanId(contractDto.getLoanId());
		paymentWithhold.setProductCode(contractDto.getProductCode());
		paymentWithhold.setProductName(contractDto.getProductName());
		paymentWithhold.setProductType(contractDto.getProductType());
		paymentWithhold.setProductTypeName(StringUtils.isEmpty(contractDto.getProductTypeName())?contractDto.getProductName():contractDto.getProductTypeName());
		if("1".equals(type)){//直接代扣
			paymentWithhold.setCustName(repaymentNoMobileDTO.getS1PayerName());
			paymentWithhold.setCustCardNo(repaymentNoMobileDTO.getS3PayerCardNo());
			paymentWithhold.setBankName(repaymentNoMobileDTO.getBankName());
			paymentWithhold.setBankCardNo(repaymentNoMobileDTO.getS4PayerBankCardNo());
			paymentWithhold.setMobile(repaymentNoMobileDTO.getS7BankMobile());
			paymentWithhold.setT2SmsCode(repaymentNoMobileDTO.getT2SmsCode());
		}else{
			paymentWithhold.setCustName(contractDto.getCustName());
			paymentWithhold.setCustCardNo(contractDto.getCustCardNo());
			paymentWithhold.setBankName(contractDto.getPaymentBankName());
			paymentWithhold.setBankCardNo(contractDto.getPaymentAcctNo());
			paymentWithhold.setMobile(contractDto.getMobile());
			//如果前端传入了卡id则需要取客户传入的银行卡信息
			if(null != repaymentNoMobileDTO.getUserBankId() && repaymentNoMobileDTO.getUserBankId().intValue() > 0){
				String paymentChannel = ServerProperties.getValue(configPropertiesPath, "common.properties", "payment_channel");
				List<McfePaymentUserBindCard> mcamPaymentUserBindCards = mcamPaymentUserBindCardMapper.selectListByIdno(contractDto.getCustCardNo(), paymentChannel, "0");
				for (McfePaymentUserBindCard mcfePaymentUserBindCard : mcamPaymentUserBindCards) {
					//如果出入的绑卡id与查询到的一致则将其设置为还款卡信息
					if(StringUtils.equalsIgnoreCase(mcfePaymentUserBindCard.getId().toString(), repaymentNoMobileDTO.getUserBankId().toString())){
						paymentWithhold.setBankName(mcfePaymentUserBindCard.getBankName());
						paymentWithhold.setBankCardNo(mcfePaymentUserBindCard.getBankCardNo());
						paymentWithhold.setMobile(mcfePaymentUserBindCard.getPhone());
					}
				}
			}
		}
		//A002 还当期  A003提前结清 A004自定义还款A005还下一期
		if("A002".equals(repaymentNoMobileDTO.getPayType()) || "A004".equals(repaymentNoMobileDTO.getPayType())){
			//还款
			paymentWithhold.setPayType(4);
			paymentWithhold.setRepayStyle("4");
			paymentWithhold.setFlowPayType("1");
			//主动还款

		}else if("A003".equals(repaymentNoMobileDTO.getPayType())){
			//提前结清  简版无需走提前结清逻辑
			paymentWithhold.setPayType(3);
			paymentWithhold.setRepayStyle("3");
			paymentWithhold.setFlowPayType("2");
		}else if("A005".equals(repaymentNoMobileDTO.getPayType())){
			//还款
			paymentWithhold.setPayType(5);
			paymentWithhold.setRepayStyle("5");
			paymentWithhold.setFlowPayType("1");
		}else if("A100".equals(repaymentNoMobileDTO.getPayType())){
			paymentWithhold.setPayType(100);
			paymentWithhold.setRepayStyle("100");
			paymentWithhold.setFlowPayType("1");
		}
	}


	@Override
	public Map queryDebt(RepaymentNoMobileDTO repaymentNoMobileDTO) throws MarvelsBusinessException {
		Map debtMap  = new HashMap();
		try {
			debtMap = reimbursementProcessDao.queryDebt(repaymentNoMobileDTO.getLoanId());
			Map<String, String> reqMap = new HashMap<>();
			reqMap.put("productType", debtMap.get("product_type") + "");
			Map<String, Object> rtnMap = consumerProductApi.queryProductInfo(reqMap);
			MarvelsLogUtil.getInstance().info("===rtnMap:" + rtnMap);
			String cycle = rtnMap.get("cycle") == null ? "" : (String) rtnMap.get("cycle");
			MarvelsLogUtil.getInstance().info("===cycle:" + cycle);
			Integer applyTerms = debtMap.get("terms") == null ? 0 : (Integer) debtMap.get("terms");
			MarvelsLogUtil.getInstance().info("===applyTerms:" + applyTerms);
			Integer cycleDay = 0;
			if(!StringUtils.isEmpty(cycle)){
				if("A000".equals(cycle)){
					cycleDay = 1;
				}else if("A001".equals(cycle)){
					cycleDay = 7;
				}else if("A002".equals(cycle)){
					cycleDay = 14;
				}else if("A003".equals(cycle)){
					cycleDay = 15;
				}else if("A004".equals(cycle)){
					cycleDay = 30;
				}else if("A005".equals(cycle)){
					cycleDay = 90;
				}
			}
			// 借款天数
			debtMap.put("borDays", applyTerms * cycleDay);

		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("=====queryDebt/{loanId}=====", e);
			throw new MarvelsApiBusinessException(MarvelsErrorCode.ERROR.getValue(),"查询失败!");
		}
		return debtMap;
	}
	@Override
	public List<Map> repayPlan(RepaymentNoMobileDTO repaymentNoMobileDTO) {
	    List<McfeCustomerRepaymentPlanDTO> mpPaymentPlanInfoList = reimbursementProcessDao.queryByLoanId(repaymentNoMobileDTO.getLoanId());
	    List<Map> listMap = new ArrayList<Map>();
	    if (CollectionUtils.isEmpty(mpPaymentPlanInfoList)) {
	      return listMap;
	    }
	    String fouStatus = null;
	    for (McfeCustomerRepaymentPlanDTO mpPaymentPlanInfo : mpPaymentPlanInfoList) {
	      Map map = new HashMap();
	      Integer status=mpPaymentPlanInfo.getStatus();
	      BigDecimal amount=mpPaymentPlanInfo.getShouldAmount();
	      //如果已还清
	      if(2 == status || 3 == status){
	        fouStatus = "A"+status;
	        amount=mpPaymentPlanInfo.getAlreadyAmount();
	      }else{
	        //如果应还金额大于已还金额，并且已还金额大于0，则未还清
	        if(mpPaymentPlanInfo.getShouldAmount().compareTo(mpPaymentPlanInfo.getAlreadyAmount())>0
	            &&mpPaymentPlanInfo.getAlreadyAmount().compareTo(new BigDecimal("0"))>0
	            && new Date().compareTo(new Date(mpPaymentPlanInfo.getPaymentDate().getTime()+1000*60*60*24)) <= 0){
	          fouStatus="A-1";
	        }else {
	          fouStatus = "A"+status;
	        }
	        amount=mpPaymentPlanInfo.getShouldAmount().subtract(mpPaymentPlanInfo.getAlreadyAmount());
	      }
	      map.put("id",mpPaymentPlanInfo.getId());
	      map.put("amount",amount);
	      map.put("paymentDate", mpPaymentPlanInfo.getPaymentDate());
	      map.put("status",fouStatus);
	      listMap.add(map);
	    }
	    return listMap;
	  }
	@Override
	public int updateBank(RepaymentNoMobileDTO repaymentNoMobileDTO)throws MarvelsBusinessException {
		if(StringUtils.isEmpty(repaymentNoMobileDTO.getLoanId()) || StringUtils.isEmpty(repaymentNoMobileDTO.getPaymentAcctName())
				||StringUtils.isEmpty(repaymentNoMobileDTO.getPaymentAcctNo()) || StringUtils.isEmpty(repaymentNoMobileDTO.getPaymentBankHead())
				||StringUtils.isEmpty(repaymentNoMobileDTO.getPaymentBankName())||StringUtils.isEmpty(repaymentNoMobileDTO.getPaymentBankBranch())){
			throw new MarvelsApiBusinessException(MarvelsErrorCode.NULL_PARAMS.getValue(),"请求参数为空!");
		}
		int count = reimbursementProcessDao.updateBank(repaymentNoMobileDTO);
		if(count == 0){
			throw new MarvelsApiBusinessException(MarvelsErrorCode.FAIL.getValue(),"修改失败!");
		}
		return count;
	}

}
